//
//  MOAssociationPickerViewController.m
//  MOED, Version 1.0
//
//  http://moed.googlecode.com/
//
//  Copyright (c) 2011, Eternity Technologies.
//  All rights reserved.
// 
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright
//      notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//    * Neither the name of the Eternity Technologies nor the
//      names of its contributors may be used to endorse or promote products
//      derived from this software without specific prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY ETERNITY TECHNOLOGIES ''AS IS'' AND ANY
//  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
//  DISCLAIMED. IN NO EVENT SHALL ETERNITY TECHNOLOGIES BE LIABLE FOR ANY
//  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
//  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
//  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
//  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
//  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

#import "MOAssociationPickerViewController.h"

#import "MOFormDescription.h"
#import "MOFormTableViewDescription.h"
#import "MOFormSection.h"
#import "MOFormField.h"

#import "MOEditorTableViewCell.h"
#import "MOEditorViewController_iPhone.h"

@implementation MOAssociationPickerViewController

@synthesize formField;
@synthesize targetObject;
@synthesize managedObjectContext;
@synthesize editorTableViewCell;
@synthesize popViewControllerOnTableRowSelected;
@synthesize fetchedResultsController;
@synthesize keywords;

- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
	if(self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
		
		self.tableView.allowsSelectionDuringEditing = YES;
		self.popViewControllerOnTableRowSelected = YES;
		
		/* Edit button */
		editBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit 
																		  target:self
																		  action:@selector(switchEntriesToEditMode:)];
		
		/* Done button */
		doneBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
																		  target:self
																		  action:@selector(switchEntriesToEditMode:)];
		
		self.toolbarItems = [NSArray arrayWithObjects:editBarButtonItem, nil];
		
		
		/* Add Button */
		UIBarButtonItem *addBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
																						  target:self 
																						  action:@selector(addAssociationObject:)];
		self.navigationItem.rightBarButtonItem = addBarButtonItem;
		[addBarButtonItem release];
		
		self.fetchedResultsController = nil;
		
	}
	return self;	
}

- (void) viewWillAppear:(BOOL)animated {

	[super viewWillAppear:animated];
	
	self.title = formField.associationForm.formName;
	self.navigationController.toolbarHidden = NO;
	self.tableView.delegate = self;
	
	NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) {
		NSLog(@"[MOAssociationPickerViewController/%@] Fetch Error", formField.associationForm.modelName);
    }
	else
		NSLog(@"[MOAssociationPickerViewController/%@] Ready", formField.associationForm.modelName);
	
	[self.tableView reloadData];
	
}


#pragma mark -
#pragma mark Memory management

- (void)dealloc {
	[keywords release];
	[doneBarButtonItem release];
	[editBarButtonItem release];
	[formField release];
	[editorTableViewCell release];
	[targetObject release];
	[fetchedResultsController release];
	[managedObjectContext release];
    [super dealloc];
}


#pragma mark -
#pragma mark Event Handlers

- (void) switchEntriesToEditMode:(id) sender {
	self.toolbarItems = !self.tableView.editing ? [NSArray arrayWithObjects:doneBarButtonItem, nil]:[NSArray arrayWithObjects:editBarButtonItem, nil];
	self.navigationItem.rightBarButtonItem.enabled = self.tableView.editing;
	[self.tableView setEditing:!self.tableView.editing animated:YES];
}

- (void) addAssociationObject:(id) sender {

	NSManagedObject *newAssociationObject = [NSEntityDescription insertNewObjectForEntityForName:formField.associationForm.modelName 
																		  inManagedObjectContext:self.managedObjectContext];
	
	[self showFormDescriptionEditorWithManagedObject:newAssociationObject deleteOnCancel:YES];
	
}

- (void) showFormDescriptionEditorWithManagedObject:(NSManagedObject *) associationObject deleteOnCancel:(BOOL) deleteOnCancel {

	MOEditorViewController_iPhone *associationEditorViewController = nil;
	associationEditorViewController = [[MOEditorViewController_iPhone alloc] initWithFormDescription:formField.associationForm];
	
	associationEditorViewController.managedObjectContext = self.managedObjectContext;
	associationEditorViewController.managedObject = associationObject;
	associationEditorViewController.deleteOnCancel = YES;
	associationEditorViewController.isModal = NO;
	associationEditorViewController.deleteOnCancel = deleteOnCancel;
	
	/* This is because current MO may not be complete */
	associationEditorViewController.saveOnDone = NO;
	
	[self.navigationController pushViewController:associationEditorViewController animated:YES];
	
	[associationEditorViewController release];
	
	
}

#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
	return [[fetchedResultsController sections] count];
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
	id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
	return [sectionInfo numberOfObjects];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"MOAssociationPickerCell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }
	
	[self configureCell:cell atIndexPath:indexPath];
    
    return cell;
}

- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
	if(!popViewControllerOnTableRowSelected)
		cell.selectionStyle = UITableViewCellSelectionStyleNone;
}

- (void) configureCell:(UITableViewCell *) cell atIndexPath:(NSIndexPath *) indexPath {
	NSManagedObject *associationEntry = [fetchedResultsController objectAtIndexPath:indexPath];
	cell.textLabel.text = [[associationEntry valueForKey:formField.associationForm.tableViewDescription.titleLabelManagedObjectKey] description];
}

#pragma mark -
#pragma mark TableView delegate

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	
	NSManagedObject *selectedAssociation = [fetchedResultsController objectAtIndexPath:indexPath];

	if(self.tableView.editing) {
		[self showFormDescriptionEditorWithManagedObject:selectedAssociation deleteOnCancel:NO];
	}
	else {
		[targetObject setValue:selectedAssociation forKey:formField.managedObjectKey];
		editorTableViewCell.textField.text = [selectedAssociation valueForKey:formField.associationForm.tableViewDescription.titleLabelManagedObjectKey];
		
		if(popViewControllerOnTableRowSelected) [self.navigationController popViewControllerAnimated:YES];
	}

}

- (void) tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 
{
	if (editingStyle == UITableViewCellEditingStyleDelete) {
		NSManagedObject *objectToDelete = [fetchedResultsController objectAtIndexPath:indexPath];
		[managedObjectContext deleteObject:objectToDelete];
		
		NSError *error;
		if (![managedObjectContext save:&error]) {
		}
	}	
}

#pragma mark -
#pragma mark Fetched Results Controllers

- (NSFetchedResultsController *) fetchedResultsController {
	
	if (fetchedResultsController != nil) return fetchedResultsController;
	
	NSLog(@"[MOAssociationPickerViewController/fetchResultsController] Model %@, Sort Order %@",  formField.associationForm.modelName, formField.associationForm.tableViewDescription.titleLabelManagedObjectKey);
    
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
	NSEntityDescription *entity = [NSEntityDescription entityForName:formField.associationForm.modelName
											  inManagedObjectContext:managedObjectContext];
	[fetchRequest setEntity:entity];
	[fetchRequest setFetchBatchSize:20];

	/* Predicate */
	if([self.keywords length] > 0) {
		
		NSMutableString *predicateString = [[NSMutableString alloc] initWithString:@"("];
		[predicateString appendString:formField.associationForm.tableViewDescription.titleLabelManagedObjectKey];
		[predicateString appendString:@" CONTAINS[cd] %@)"];
		
		NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString, self.keywords];
		[fetchRequest setPredicate:predicate];
		
		[predicateString release];
		
	}
	
	NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:formField.associationForm.tableViewDescription.titleLabelManagedObjectKey 
																   ascending:YES];
	NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    
	[fetchRequest setSortDescriptors:sortDescriptors];
	
	NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
																								managedObjectContext:managedObjectContext 
																								  sectionNameKeyPath:nil 
																										   cacheName:nil];
	
	aFetchedResultsController.delegate = self;
	self.fetchedResultsController = aFetchedResultsController;
    
	[aFetchedResultsController release];
	[fetchRequest release];
	[sortDescriptor release];
	[sortDescriptors release];
	
	return fetchedResultsController;
	
}


#pragma mark -
#pragma mark Fetched results controller delegate

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
	[self.tableView beginUpdates];
}


- (void) controller:(NSFetchedResultsController *)controller 
   didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
			atIndex:(NSUInteger)sectionIndex 
	  forChangeType:(NSFetchedResultsChangeType)type 
{
	
	switch(type) {
		case NSFetchedResultsChangeDelete:
			[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] 
						  withRowAnimation:UITableViewRowAnimationFade];
			break;
	}
}


- (void) controller:(NSFetchedResultsController *)controller 
	didChangeObject:(id)anObject
		atIndexPath:(NSIndexPath *)indexPath 
	  forChangeType:(NSFetchedResultsChangeType)type
	   newIndexPath:(NSIndexPath *)newIndexPath 
{
	
	UITableView *tableView = self.tableView;
	
	switch(type) {
		case NSFetchedResultsChangeInsert:
			[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] 
							 withRowAnimation:UITableViewRowAnimationFade];
			break;
			
		case NSFetchedResultsChangeUpdate:
			[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
			break;
			
		case NSFetchedResultsChangeDelete:
			[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
							 withRowAnimation:UITableViewRowAnimationFade];
			break;

		case NSFetchedResultsChangeMove:
			[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] 
							 withRowAnimation:UITableViewRowAnimationFade];
			[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
							 withRowAnimation:UITableViewRowAnimationFade];
			break;
	}
}


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
	[self.tableView endUpdates];
}



#pragma mark -
#pragma mark Search Display Delegate

- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
	self.keywords = [searchString isEqualToString:@""] ? nil:searchString;
	self.fetchedResultsController = nil;
	NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) {

		// Error
    
	}	
	return YES;
}

-(void) searchBarCancelButtonClicked:(UISearchBar *)searchBar {
	
	self.keywords = nil;
	self.fetchedResultsController = nil;
	NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) {
		// Error
    }	
	
}

@end

